﻿using System;
using System.Collections.Generic;
using System.Linq;
using Ewk.MachineLearning.Classification.Common;
using Ewk.MachineLearning.Classification.Interfaces;
using Ewk.MachineLearning.Persistance.DataAccess;
using Ewk.MachineLearning.Persistance.Domain;

namespace Ewk.MachineLearning.Classification.Conversions.EntityVectorFactories
{
    /// <summary>
    /// Creates a vector representation of a <see cref="Category"/>.
    /// </summary>
    class CategoryVectorFactory : IEntityVectorFactory
    {
        #region Implementation of IEntityFactory

        /// <summary>
        /// Creates a vector representation of the <see cref="Category"/>.
        /// </summary>
        /// <returns>A vector representation of the <see cref="Category"/>.</returns>
        public EntityVector<double>[] CreateEntityVectors()
        {
            using (var catalog = CatalogFactory.NewCatalog())
            {
                var categoryRepository = new TextEntityRepository<Category>(catalog);
                var categories = categoryRepository.Entities;

                var wordRepository = new TextEntityRepository<Word>(catalog);
                var words = wordRepository.Entities
                    .Cast<IEntity>()
                    .ToList();

                return categories
                    .Select(category =>
                            CreateEntityVector(wordRepository, category, words))
                    .ToArray();
            }
        }

        #endregion

        private static EntityVector<double> CreateEntityVector(TextEntityRepository<Word> repository,
                                                               TextEntity category,
                                                               List<IEntity> words)
        {
            var wordsInCategory = category.Content
                                .GetTextEntities(repository)
                                .ToList();
            var tempCategory = new Category {Id = Guid.Empty};
            tempCategory.LinkToFeatures<Category, Word, WordInCategoryLink>(wordsInCategory);

            return new EntityVector<double>(
                category.Id.ToString(),
                tempCategory.ToVector<Category, Word>(words));
        }
    }
}